﻿using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration.Install;
using System.IO;
using System.Reflection;
using System.Security.Policy;
using System.ServiceProcess;
using System.Text;
using WatchDog.ServiceProcess;

namespace WatchDog
{
    public class WindowsServiceManage
    {
        /// <summary>
        /// 判断服务是否存在
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool IsServiceExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.Equals(serviceName, StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="serviceFilePath"></param>
        public static string InstallService(string serviceFilePath)
        {
            try
            {
                var serviceProcessInstaller1 = new ServiceProcessInstaller();
                var serviceInstaller1 = new ServiceInstaller();

                // 
                // serviceProcessInstaller1
                // 
                serviceProcessInstaller1.Account = ServiceAccount.LocalSystem;
                serviceProcessInstaller1.Password = null;
                serviceProcessInstaller1.Username = null;
                // 
                // serviceInstaller1
                // 
                serviceInstaller1.Description = "兆益GPS系统值守服务";
                serviceInstaller1.DisplayName = "ZWatchDog";
                serviceInstaller1.ServiceName = "ZWatchDog";
                serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
                serviceInstaller1.DelayedAutoStart = true;
           
                using (var installer = new AssemblyInstaller())
                {
            //        installer.Installers.AddRange(new System.Configuration.Install.Installer[] {
            //serviceProcessInstaller1,
            //serviceInstaller1});


                    if (System.IO.Path.GetExtension(serviceFilePath).ToLower() == ".dll")
                    {
                        var logFilePath = System.IO.Path.ChangeExtension(serviceFilePath, ".InstallLog");
                        var assemblyPath = System.IO.Path.ChangeExtension(serviceFilePath, ".exe");
                        installer.UseNewContext = false;
                        installer.Path = serviceFilePath;
                        installer.Context = new InstallContext(logFilePath, new string[0]);
                        installer.Context.Parameters["assemblyPath"] = assemblyPath;
                       
                    }
                    else
                    {
                        installer.UseNewContext = true;
                        installer.Path = serviceFilePath;
                    }
 
                    IDictionary savedState = new Hashtable();
                    installer.Install(savedState);
                    installer.Commit(savedState);
                }
            }
            catch (Exception ex)
            {
                //try
                //{
                //    installer.Rollback(state);
                //}
                //catch { }
                return ex.Message;
            }
            return null;
        }
         
        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="serviceFilePath"></param>
        public static string UninstallService(string serviceFilePath)
        {
            try
            {
                using (var installer = new AssemblyInstaller())
                {
                    if (System.IO.Path.GetExtension(serviceFilePath).ToLower() == ".dll")
                    {
                        var logFilePath = System.IO.Path.ChangeExtension(serviceFilePath, ".InstallLog");
                        var assemblyPath = System.IO.Path.ChangeExtension(serviceFilePath, ".exe");
                        installer.UseNewContext = false;
                        installer.Path = serviceFilePath;
                        installer.Context = new InstallContext(logFilePath, new string[0]);
                        installer.Context.Parameters["assemblyPath"] = assemblyPath;
                    }
                    else
                    {
                        installer.UseNewContext = true;
                        installer.Path = serviceFilePath;
                    }

                    installer.Uninstall(null);
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return null;
        }
         
        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="serviceName"></param>
        public static string ServiceStart(string serviceName)
        {
            //var timeout = TimeSpan.FromSeconds(60);
            using (var service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Stopped)
                    {
                        service.Start();
                        service.WaitForStatus(ServiceControllerStatus.Running);
                    }
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
            return null;
        }
         

        /// <summary>
        /// 向服务发送命令
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="command">一个应用程序定义的命令标志，指示要执行的自定义命令。该值必须介于 128 和 256 之间</param>
        public static string ExecuteCommand(string serviceName, WindowsServiceCustomCommands command)
        {
            using (var service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Running)
                    {
                        service.ExecuteCommand((int)command);
                    }
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
            return null;
        }
        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="serviceName"></param>
        public static string ServiceStop(string serviceName)
        {
            using (var service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Running)
                    {
                        service.Stop();
                        service.WaitForStatus(ServiceControllerStatus.Stopped);
                    }
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
            return null;
        }

        /// <summary>
        /// 重启服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static string ServiceRestart(string serviceName)
        {
            using (var service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Running)
                    {
                        service.Stop();
                        service.WaitForStatus(ServiceControllerStatus.Stopped);
                    }
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running);
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
            return null;
        }

        /// <summary>
        /// 获取服务状态
        /// </summary>
        /// <returns></returns>
        public static ServiceControllerStatus GetServiceStatus(string serviceName)
        {
            using (var serviceController = new ServiceController(serviceName))
                return serviceController.Status;

        }


        private static void CorrectAssemblyPath(InstallContext context)
        {
            string possibleDll = context.Parameters["assemblyPath"];

            if (possibleDll == null)
            {
                return;
            }

            if (possibleDll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
            {
                var exe = possibleDll.Substring(0, possibleDll.Length - 4) + ".exe";
                context.Parameters["assemblyPath"] = exe;
            }
        }

    }
}
